﻿using AutoMapper;
using BaseRepository.Redis;
using Common;
using Common.DataModels;
using Extensions.Attribute.EventAttribute;
using Microsoft.EntityFrameworkCore;
using PLC.Domain.Dto;
using PLC.Domain.Entity;
using PLC.Domain.Enum;
using PLC.Domain.Models;
using PLC.Domain.ScheduledTasks;
using PLC.Domain.Service.IRepository;

namespace PLC.Domain.Service.Service;

public class DeviceConfigService
{
    private readonly IMapper _mapper;
    private readonly IDeviceConfigRepository _deviceConfigRepository;
    private readonly IRedisRepository _redisRepository;

    public DeviceConfigService(IMapper mapper,IDeviceConfigRepository deviceConfigRepository,IRedisRepository redisRepository)
    {
        _mapper = mapper?? throw new ArgumentNullException(nameof(mapper));
        _deviceConfigRepository = deviceConfigRepository?? throw new ArgumentNullException(nameof(deviceConfigRepository));
        _redisRepository = redisRepository?? throw new ArgumentNullException(nameof(redisRepository));
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="pagingModel"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public virtual async Task<Tuple<List<DtoDeviceConfig>, int>> FindByPageAsync(PagingModel pagingModel)
    {
        var expression = ExpressionExtensions.True<DeviceConfig>().And(p => !p.IsDelete);
        if (!string.IsNullOrWhiteSpace( pagingModel.key))
        {
            expression = expression.And(p => p.DeviceName.Contains(pagingModel.key));
        }
        var result =
            await _deviceConfigRepository.GetEntitiesByPageAsync(expression, pagingModel.sort, pagingModel.page, pagingModel.rows);
        return new Tuple<List<DtoDeviceConfig>, int>(_mapper.Map<List<DtoDeviceConfig>>(result.Item1), result.Item2);
    }
    /// <summary>
    /// 查询所有的设备配置
    /// </summary>
    /// <returns></returns>
    public virtual async Task<List<DeviceConfig>> FindPLCDeviceAll()
    {
        return await _deviceConfigRepository.GetEntitiesAsync(p => !p.IsDelete&&p.Status==(int)EnumStatus.启用&&p.HardwareType==(int)EnumHanHardwareType.PLC);
    }
    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    [Event("DeleteDeviceCache",EnumEventPosition.After)]
    public virtual async Task<DtoDeviceConfig> UpdateAsync(DtoDeviceConfig entity)
    {
        var barcodeData = await _deviceConfigRepository.GetEntityAsync(p => p.Id == entity.id && !p.IsDelete);
        ArgumentNullException.ThrowIfNull(barcodeData);
        _mapper.Map(entity, barcodeData);
        await _deviceConfigRepository.UpdateAsync(barcodeData);
        return entity;
    }
    /// <summary>
    /// 精确查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public virtual async Task<DtoDeviceConfig> FindOneAsync(long id)
    {
        var data = await _deviceConfigRepository.GetEntityAsync(p => p.Id == id && !p.IsDelete);
        ArgumentNullException.ThrowIfNull(data);
        return _mapper.Map<DtoDeviceConfig>(data);
    }
    /// <summary>
    /// 新增
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    [Event("DeleteDeviceCache", EnumEventPosition.After)]
    public virtual async Task<DtoDeviceConfig> CreateAsync(DtoDeviceConfig entity)
    {
        var data = _mapper.Map<DeviceConfig>(entity).Build();
        await _deviceConfigRepository.CreateAsync(data);
        return _mapper.Map<DtoDeviceConfig>(data);
    }
    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="ids"></param>
    [Event("DeleteDeviceCache", EnumEventPosition.After)]
    public virtual async Task DeleteAsync(IEnumerable<long> ids)
    {
        ArgumentNullException.ThrowIfNull(ids);
        await _deviceConfigRepository.Qyery.Where(p => ids.Contains(p.Id))
            .ExecuteUpdateAsync(p => p.SetProperty(o => o.IsDelete, true));
    }
    /// <summary>
    /// 测试和plc的通讯
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public virtual async Task<bool> CommunicationTest(long id)
    {
        if (id==default(long))
        {
            throw new ArgumentNullException(nameof(id));
        }
        var data  =await FindOneAsync(id);
        var client =  PLCHelper.Get(data.Ip);
        if (client==null)
        {
            return false;
        }
        var config = Appsettings.app<OperationalConfig>("OperationalConfig");
        if (config==null||string.IsNullOrWhiteSpace(config.TestBit))
        {
            throw new Exception("没有配置测试读取位，请检查");
        }
        var result=  client.ReadBool(config.TestBit);
        return result.IsSuccess;
    }
}